Skip to content

Add iommu support to microkit#467

Draft
Cheng-Li1 wants to merge 8 commits into
seL4:mainfrom
au-ts:cheng/iommu-support
Draft

Add iommu support to microkit#467
Cheng-Li1 wants to merge 8 commits into
seL4:mainfrom
au-ts:cheng/iommu-support

Conversation

@Cheng-Li1

Copy link
Copy Markdown

This pull request adds iommu support for Microkit and needs Rust-Sel4 with the iommu support to work.

Supported features:
Map the memory region to a device-visible memory address.

Tests done:
Blk example with iommu feature enabled on x86 qemu and hardware(vb-105).

Comment thread Cargo.toml Outdated
Comment thread tool/microkit/src/capdl/iomem.rs
Comment thread tool/microkit/src/capdl/iomem.rs
Comment thread tool/microkit/src/sdf.rs
Comment thread tool/microkit/tests/test.rs Outdated
Comment thread tool/microkit/src/capdl/initialiser.rs Outdated
Comment thread tool/microkit/src/capdl/iomem.rs Outdated
sel4::Config,
};

// VTD Page table level is defaulted to the three-level structure even if the hardware supports four level.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I forgot the content of the conversation we had offline about this. But what happens when the target machine only support 3 levels VT-d page table, but we made a 4 levels one (according to VTD_PAGE_TABLE_LEVEL)?

@dreamliner787-9

Copy link
Copy Markdown
Contributor

Your commit history needs to be cleaned up and squashed. Some of the commits checked in code that should not be in Microkit, then other commits removed them.

@dreamliner787-9

Copy link
Copy Markdown
Contributor

A nice to have would be a minimal example showing this in action on QEMU x86, like the arm_smc or x86_64_ioport examples, as a proof that it works.

For example, you can use QEMU's DMA-capable "educational device": https://www.qemu.org/docs/master/specs/edu.html. You copy some data from normal RAM into the device's SRAM with a DMA transaction, then read back the device's SRAM via normal MMIO to verify that the transfer succeeded.

@midnightveil midnightveil left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Misc things.

I'm not quite sure how this is supposed to be used in the SDF file.

I can only vaguely infer from the error tests you added, but you should add documentation on how to use this and what that means for the layout of the page tables for both.

use sel4_capdl_initializer_types::{
object, CapTableEntry, Fill, FillEntry, FillEntryContent, NamedObject, Object, ObjectId, Spec,
Word,
object::{self},

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why object::{self}. What was wrong with just object?

Comment on lines +398 to +400
for frame_obj_id in frames.iter() {
// Make a cap for this frame.
let frame_cap = capdl_util_make_frame_cap(*frame_obj_id, read, write, false, false);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
for frame_obj_id in frames.iter() {
// Make a cap for this frame.
let frame_cap = capdl_util_make_frame_cap(*frame_obj_id, read, write, false, false);
for &frame_obj_id in frames.iter() {
// Make a cap for this frame.
let frame_cap = capdl_util_make_frame_cap(frame_obj_id, read, write, /* what does this mean */ false, /* what does this mean */ false);

Comment thread tool/microkit/src/capdl/builder.rs Outdated
// Step 3-4 Create Scheduling Context
// Step 3-4 Create and Map IO Page Table Structure
if kernel_config.iommu {
let mut pci_to_iospace: HashMap<(u8, u8, u8), ObjectId> = HashMap::new();

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is assuming x86-specificness.

Do we not have a PciDev type anyway, that would make this nicer

also what happened to the domain id from the rust-seL4 pr?

Comment thread tool/microkit/src/capdl/iomem.rs Outdated
};

// VTD Page table level is defaulted to the three-level structure even if the hardware supports four level.
// Sel4 will only attempt to use the four-level structure if the hardware does not supports three level.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

seL4.
Check the grammar.

Comment thread tool/microkit/src/capdl/iomem.rs Outdated

// VTD Page table level is defaulted to the three-level structure even if the hardware supports four level.
// Sel4 will only attempt to use the four-level structure if the hardware does not supports three level.
// https://github.com/seL4/seL4/blob/c406015c389decc4559fd44cb69604ddd24a0ddb/src/plat/pc99/machine/intel-vtd.c#L498

@midnightveil midnightveil Apr 16, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use a link to a commit tag preferably over a random commit hash, e.g. seL4/seL4/blob/15.0.0.

Also, seL4 not Sel4

Comment thread tool/microkit/src/sdf.rs
Comment on lines +161 to +167
pub name: String,
pub pci_bus: u8,
pub pci_dev: u8,
pub dev_func: u8,
pub ioaddr: u64,
pub perms: u8,
pub text_pos: Option<roxmltree::TextPos>,

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comments as the rust-seL4 PR: the PCI stuff should be part of x86 as itis arch-speicific.

Comment thread tool/microkit/src/sdf.rs Outdated
if map_end > crate::capdl::iomem::VTD_MAX_ADDR {
return Err(
format!(
"Error: iomap for '{}' has address 0x{:x} which exceeds the upper limits of {} in {} '{}' @ {}",

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

{:#x}.

Comment thread tool/microkit/src/sel4.rs Outdated
},
ObjectType::AsidPool => Some(object_sizes.asid_pool),
ObjectType::IOPageTable => Some(12),
// It would be best to avoid such catch all case so people might forget to add the size of new object type here.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fix it or make an issue I think

@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright 2024, UNSW.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

year

Comment thread build_sdk.py Outdated
@@ -68,7 +68,7 @@
"KernelPlatform": "pc99",
"KernelX86MicroArch": "generic",
# See https://github.com/seL4/microkit/issues/418 for details.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove this comment if its solved

@Cheng-Li1 Cheng-Li1 force-pushed the cheng/iommu-support branch 4 times, most recently from 704b840 to 481926e Compare May 11, 2026 07:33
@Cheng-Li1

Cheng-Li1 commented Jun 10, 2026

Copy link
Copy Markdown
Author

Things left to do:

  1. Sort out the problem of the three-level vs four-level IO page table.
  2. Implement the minimal IOMMU example.
  3. Integrate with sdfgen.
  4. Resolve other minor issues.

The issue behind the three-level vs four-level IO page table is that the IO page table level the seL4 will select for the board to use is only known at runtime. When generating the spec, the program has to assume a three-level or four-level IO page table structure, causing a potential mismatch. Currently, the program assumes a four-level IO page table structure, but only accepts memory regions that can fit into the three-level IO page table structure. At runtime, if the three-level IO page table is selected by seL4, the capdl initializer will skip mapping the root page table object, effectively treating the structure as a three-level IO page table. However, this approach will unnecessarily waste the memory because the root page table object is not mapped in. A better approach is to default the IO page table to three-level, but generate another page table object in the capdl initializer on demand. However, it might be tricky to implement due to how objects are generated in the capdl initializer.

Signed-off-by: Cheng Li <cheng.li10@unsw.edu.au>
Signed-off-by: Cheng Li <cheng.li10@unsw.edu.au>
Signed-off-by: Cheng Li <cheng.li10@unsw.edu.au>
Signed-off-by: Cheng Li <cheng.li10@unsw.edu.au>
Perms and setvar are supported.
Page size optimization logic has been refined.

Signed-off-by: Cheng Li <cheng.li10@unsw.edu.au>
Fix the issue of duplicate objects names conflict when one pd owns
multiple iospaces.

Signed-off-by: Cheng Li <cheng.li10@unsw.edu.au>
Signed-off-by: Cheng Li <cheng.li10@unsw.edu.au>
Signed-off-by: Cheng Li <cheng.li10@unsw.edu.au>
@Cheng-Li1 Cheng-Li1 force-pushed the cheng/iommu-support branch from 4e515b3 to 4f84e0e Compare June 10, 2026 05:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants